// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#pragma once

#include <memory>

#include <nebula/csv/options.h>
#include <nebula/io/interfaces.h>
#include <nebula/ipc/type_fwd.h>
#include <nebula/core/record_batch.h>
#include <nebula/core/table.h>

namespace nebula::csv {

    // Functionality for converting Nebula data to Comma separated value text.
    // This library supports all primitive types that can be cast to a StringArray or
    // a LargeStringArray.
    // It applies to following formatting rules:
    //  - For non-binary types no quotes surround values.  Nulls are represented as the empty
    //  string.
    //  - For binary types all non-null data is quoted (and quotes within data are escaped
    //  with an additional quote).
    //    Null values are empty and unquoted.

    /// \defgroup csv-write-functions High-level functions for writing CSV files
    /// @{

    /// \brief Convert table to CSV and write the result to output.
    /// Experimental
    TURBO_EXPORT turbo::Status write_csv(const Table &table, const WriteOptions &options,
                                 nebula::io::OutputStream *output);
    /// \brief Convert batch to CSV and write the result to output.
    /// Experimental
    TURBO_EXPORT turbo::Status write_csv(const RecordBatch &batch, const WriteOptions &options,
                                 nebula::io::OutputStream *output);
    /// \brief Convert batches read through a RecordBatchReader
    /// to CSV and write the results to output.
    /// Experimental
    TURBO_EXPORT turbo::Status write_csv(const std::shared_ptr<RecordBatchReader> &reader,
                                 const WriteOptions &options,
                                 nebula::io::OutputStream *output);

    /// @}

    /// \defgroup csv-writer-factories Functions for creating an incremental CSV writer
    /// @{

    /// \brief create a new CSV writer. User is responsible for closing the
    /// actual OutputStream.
    ///
    /// \param[in] sink output stream to write to
    /// \param[in] schema the schema of the record batches to be written
    /// \param[in] options options for serialization
    /// \return turbo::Result<std::shared_ptr<RecordBatchWriter>>
    TURBO_EXPORT
    turbo::Result<std::shared_ptr<ipc::RecordBatchWriter>> make_csv_writer(
            std::shared_ptr<io::OutputStream> sink, const std::shared_ptr<Schema> &schema,
            const WriteOptions &options = WriteOptions::defaults());

    /// \brief create a new CSV writer.
    ///
    /// \param[in] sink output stream to write to (does not take ownership)
    /// \param[in] schema the schema of the record batches to be written
    /// \param[in] options options for serialization
    /// \return turbo::Result<std::shared_ptr<RecordBatchWriter>>
    TURBO_EXPORT
    turbo::Result<std::shared_ptr<ipc::RecordBatchWriter>> make_csv_writer(
            io::OutputStream *sink, const std::shared_ptr<Schema> &schema,
            const WriteOptions &options = WriteOptions::defaults());

    /// @}

}  // namespace nebula::csv
